<?php
/**
 * This file is part of Hyperf Mall.
 *
 * @link     https://gitee.com/scwlkj/hyperf_mall
 * @contact  hyperf_mall@163.com
 */

namespace App\JsonRpc;

use App\Model\BaseModel;
use App\Model\Model;
use App\Repository\BaseRepository;
use App\Utils\Log;

abstract class BaseService
{
    const SUCCESS_CODE = 200;
    const ERROR_CODE = 0;
    const SUCCESS_MSG = 'success';

    /**
     * @var BaseRepository
     */
    protected $repository;

    abstract public function init();

    public function initFunction($args): array
    {
        set_start_time(microtime(true));

        $method = array_shift($args);
        $common = array_shift($args);
        $saas_id = $common['saas_id'] ?? 0;

        set_saas_id((int)$saas_id);
        set_current_db(getDb());

        try {
            $this->init();// 初始化服务repository

            $res = $this->$method(...$args);
            return $this->returnSuccess($res);
        } catch (\Throwable $e) {
            Log::getInstance()->error(__METHOD__, ['exception' => $e, 'trace' => $e->getTraceAsString()]);

            $data = [
                'msg' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString(),
            ];

            return $this->returnError($e->getMessage(), $data);
        }
    }

    /**
     * Author: Bruce.z
     * @param $data
     * @return array
     */
    public function returnSuccess($data): array
    {
        return [
            'code' => self::SUCCESS_CODE,
            'msg' => self::SUCCESS_MSG,
            'data' => $data,
            'elapsed' => round(microtime(true) - get_start_time(), 6),
        ];
    }

    /**
     * @param $msg
     * @param array $data
     * @return array
     */
    public function returnError($msg, array $data = []): array
    {
        return [
            'code' => self::ERROR_CODE,
            'msg' => $msg,
            'data' => $data,
            'elapsed' => round(microtime(true) - get_start_time(), 6),
        ];
    }

    /**
     * Notes: 默认列表
     * Author: Bruce.z
     * DateTime: 2021/12/22 19:51
     * @param array $condition
     * @param array $field
     * @param int $page
     * @param int $size
     * @return array
     */
    public function index(array $condition, array $field, int $page, int $size) : array
    {
        $condition = array_filter($condition);
        return $this->repository->getPageRows($condition, $field, $page, $size);
    }

    /**
     * Notes: 默认详情
     * Author: Bruce.z
     * DateTime: 2021/12/22 19:51
     * @param int $id
     * @return array
     */
    public function detail(int $id) :array
    {
        if(method_exists($this->repository, 'detail')){
            return $this->repository->detail($id);
        }else{
            return $this->repository->getOne(['id'=>$id]);
        }
    }

    /**
     * Notes: 默认编辑
     * Author: Bruce.z
     * DateTime: 2021/12/22 19:52
     * @param $id
     * @param array $data
     * @return bool
     */
    public function update(int $id, array $data) : bool
    {
        return $this->repository->updateByConditions(['id'=>$id], $data);
    }

    /**
     * Notes: 默认删除
     * Author: Bruce.z
     * DateTime: 2021/12/22 19:53
     * @param int $id
     * @return bool
     */
    public function delete(int $id):bool
    {
        return $this->repository->baseRemove($id);
    }

    /**
     * Notes: 默认添加
     * Author: Bruce.z
     * DateTime: 2021/12/22 20:17
     * @param array $data
     * @return BaseModel|Model
     */
    public function add(array $data)
    {
        return $this->repository->baseAdd($data);
    }

    /**
     * Notes: 根据条件获取列表数据
     * Author: Bruce.z
     * DateTime: 2022/7/1 14:06
     * @param array $condition
     * @param array $field
     * @return array
     */
    public function getRows(array $condition, array $field):array
    {
        return $this->repository->getRows($condition, $field);
    }

    /**
     * Notes: 根据条件获取单条数据
     * Author: Bruce.z
     * DateTime: 2022/7/1 14:07
     * @param array $condition
     * @param array $field
     * @return array
     */
    public function getOne(array $condition, array $field = ['*']):array
    {
        return $this->repository->getOne($condition, $field);
    }
}
